package com.sl.proxy.server.dao.mapper;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.sl.proxy.server.constant.EnableStatusEnum;
import com.sl.proxy.server.controller.req.proxy.PortMappingListReq;
import com.sl.proxy.server.dao.domain.entity.PortMappingDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * @author: aoshiguchen
 * @date: 2022/8/8
 */
@Mapper
public interface PortMappingMapper extends BaseMapper<PortMappingDO> {

    default PortMappingDO findById(String id) {
        return this.selectById(id);
    }

    default void updateEnableStatus(String id, Integer enable, Date updateTime) {
        this.update(null, new LambdaUpdateWrapper<PortMappingDO>()
                .eq(PortMappingDO::getId, id)
                .set(PortMappingDO::getEnable, enable)
                .set(PortMappingDO::getModifyTime, updateTime)
        );
    }

    default PortMappingDO findByPort(Integer port, Set<String> excludeIds) {
        return this.selectOne(new LambdaQueryWrapper<PortMappingDO>()
                .eq(PortMappingDO::getServerPort, port)
                .notIn(!CollectionUtil.isEmpty(excludeIds), PortMappingDO::getId, excludeIds)
                .last("limit 1")
        );
    }

    /**
     * 校验子域名是否重复
     *
     * @param subdomain
     * @return
     */
    default Boolean checkRepeatBySubdomain(String subdomain, Set<String> excludeIds) {
        return StringUtils.isEmpty(subdomain) ? Boolean.FALSE : this.selectCount(new LambdaQueryWrapper<PortMappingDO>()
                .eq(PortMappingDO::getSubdomain, subdomain)
                .notIn(!CollectionUtil.isEmpty(excludeIds), PortMappingDO::getId, excludeIds)
        ).intValue() > 0;
    }

    default List<PortMappingDO> findEnableListByLicenseId(String licenseId) {
        return this.selectList(new LambdaQueryWrapper<PortMappingDO>()
                .eq(PortMappingDO::getLicenseId, licenseId)
                .eq(PortMappingDO::getEnable, EnableStatusEnum.ENABLE.getStatus())
        );
    }

    default List<PortMappingDO> findListByServerPort(Integer serverPort) {
        return this.selectList(new LambdaQueryWrapper<PortMappingDO>()
                .eq(PortMappingDO::getServerPort, serverPort)
        );
    }

    default List<PortMappingDO> findListByLicenseId(String licenseId) {
        return this.selectList(new LambdaQueryWrapper<PortMappingDO>()
                .eq(PortMappingDO::getLicenseId, licenseId)
        );
    }

    default PortMappingDO findByLicenseIdAndServerPort(String licenseId, Integer serverPort) {
        return this.selectOne(new LambdaQueryWrapper<PortMappingDO>()
                .eq(PortMappingDO::getLicenseId, licenseId)
                .eq(PortMappingDO::getServerPort, serverPort)
                .last("limit 1")
        );
    }

    default void updateOnlineStatus(String licenseId, Integer serverPort, Integer isOnline, Date updateTime) {
        this.update(null, new LambdaUpdateWrapper<PortMappingDO>()
                .eq(PortMappingDO::getLicenseId, licenseId)
                .eq(PortMappingDO::getServerPort, serverPort)
                .set(PortMappingDO::getIsOnline, isOnline)
                .set(PortMappingDO::getModifyTime, updateTime)
        );
    }

    default void updateOnlineStatus(String licenseId, Integer isOnline, Date updateTime) {
        this.update(null, new LambdaUpdateWrapper<PortMappingDO>()
                .eq(PortMappingDO::getLicenseId, licenseId)
                .set(PortMappingDO::getIsOnline, isOnline)
                .set(PortMappingDO::getModifyTime, updateTime)
        );
    }

    default void updateOnlineStatus(Integer isOnline, Date updateTime) {
        this.update(null, new LambdaUpdateWrapper<PortMappingDO>()
                .set(PortMappingDO::getIsOnline, isOnline)
                .set(PortMappingDO::getModifyTime, updateTime)
        );
    }

    List<PortMappingDO> selectPortMappingByCondition(IPage<PortMappingDO> page, @Param("req") PortMappingListReq req);
}
